﻿//========================================================= 
/**@file DevReader_CmdDriver.h
 * @brief 读卡器硬件控制驱动
 * 
 * @date 2017-02-11   09:54:30
 * @author Zhyioo 
 * @version 1.0
 */ 
//--------------------------------------------------------- 
#ifndef _LIBZHOUYB_DEVREADER_CMDDRIVER_H_
#define _LIBZHOUYB_DEVREADER_CMDDRIVER_H_
//--------------------------------------------------------- 
#include "../CommonCmdDriver.h"

#include "../../device/ComIC_ReaderDevAdapter.h"
using zhou_yb::application::device::ComIC_ReaderDevAdapter;
//--------------------------------------------------------- 
namespace zhou_yb {
namespace application {
namespace driver {
//--------------------------------------------------------- 
/// 读卡器设备控制命令驱动
class DevReader_CmdDriver :
    public CommonCmdDriver,
    public BaseDevAdapterBehavior<IInteractiveTrans>
{
protected:
    ComICCardCmdAdapter _cmdAdapter;
    ComIC_ReaderDevAdapter _reader;
public:
    DevReader_CmdDriver() : CommonCmdDriver()
    {
        _errGetter.Add(_reader)
            .Select("IcCMD", _cmdAdapter);

        select_helper<LoggerSetter::SelecterType>::select(_logSetter),
            _cmdAdapter, _reader;
        _reader.SelectDevice(_cmdAdapter);

        _RegisteAdapterCMD(DevReader_CmdDriver);

        _RegisteCMD(DevReader_CmdDriver, Transmit);
        _RegisteCMD(DevReader_CmdDriver, HasContactCard);
        _RegisteCMD(DevReader_CmdDriver, HasContactlessCard);
        _RegisteCMD(DevReader_CmdDriver, SetDevBaud);
        _RegisteCMD(DevReader_CmdDriver, GetVersion);
        _RegisteCMD(DevReader_CmdDriver, ResetReader);
        _RegisteCMD(DevReader_CmdDriver, BuzzerControl);
        _RegisteCMD(DevReader_CmdDriver, LedControl);
        _RegisteCMD(DevReader_CmdDriver, SetUpdateMode);
        _RegisteCMD(DevReader_CmdDriver, SetSW_Mode);
        _RegisteCMD(DevReader_CmdDriver, GetContactlessCardCount);
        _RegisteCMD(DevReader_CmdDriver, HaltAerial);
    }
    LC_CMD_ADAPTER_INVOKE(IInteractiveTrans, _cmdAdapter);
    /**
     * @brief 发送控制指令
     * @date 2017-02-11 14:50
     * 
     * @param [in] Send : hex 发送的控制指令
     * 
     * @retval Recv : hex 接收到的回应数据
     * @retval StatusCode : uint 设备返回的状态码
     */
    LC_CMD_METHOD(Transmit)
    {
        string sCmd = arg["Send"].To<string>();
        ByteBuilder send(8);
        DevCommand::FromAscii(sCmd.c_str(), send);

        ByteBuilder recv(8);
        ushort statusCode = 0x00;

        if(!ComIC_ReaderDevAdapter::Transmit(_pDev, send, recv, &statusCode))
        {
            _logErr(DeviceError::TransceiveErr, "Transmit失败");
            return false;
        }

        rlt.Put("Recv", ArgConvert::ToString(recv));
        rlt.Put("StatusCode", ArgConvert::ToString<uint>(statusCode));
        return true;
    }
    /**
     * @brief 返回当前设备上是否有接触式卡
     * @date 2017-02-11 14:57
     * 
     * @param [in] SLOT : byte [default:0x00] 需要识别的卡槽号
     * 
     * @retval HasCard : bool 是否有卡
     * @retval HasPowerOn : bool 是否已上电
     */
    LC_CMD_METHOD(HasContactCard)
    {
        byte slot = arg["SLOT"].To<byte>(0x00);
        return true;
    }
    /**
     * @brief 返回当前设备上是否有非接触式卡
     * @date 2017-02-11 14:58
     * 
     * @retval HasCard : bool 是否有卡
     * @retval HasPowerOn : bool 是否已上电
     * @retval HasMultiCard : bool 是否有多张卡
     */
    LC_CMD_METHOD(HasContactlessCard)
    {
        return true;
    }
    /**
     * @brief 设置设备通讯的波特率
     * @date 2017-02-11 14:59
     * 
     * @param [in] Baud : uint [default:9600] 需要设置的通讯波特率
     * - 支持的波特率:
     *  - 9600
     *  - 19200
     *  - 38400
     *  - 57600
     *  - 115200
     * .
     */
    LC_CMD_METHOD(SetDevBaud)
    {
        uint baud = arg["Baud"].To<uint>(9600);
        return _reader.SetDevBaud(baud);
    }
    /**
     * @brief 获取设备版本信息
     * @date 2017-02-11 14:59
     *
     * @param [in] IsHex : bool [default:false] 是否直接以16进制格式的字符串导出
     * 
     * @retval Version : hex 获取到的版本信息
     */
    LC_CMD_METHOD(GetVersion)
    {
        ByteBuilder version(8);
        if(!_reader.GetVersion(version))
            return false;
        bool isHex = arg["IsHex"].To<bool>(false);
        ByteConvert::ToString(isHex, version);
        rlt.Put("Version", version.GetString());
        return true;
    }
    /**
     * @brief 软复位读卡器
     * @date 2017-02-11 15:03
     */
    LC_CMD_METHOD(ResetReader)
    {
        return _reader.ResetReader();
    }
    /**
     * @brief 蜂鸣器控制
     * @date 2017-02-11 10:03
     * 
     * @param [in] Duration : uint [default:1] 持续时间(100ms)
     * @param [in] Interval : uint [default:0] 每次鸣叫的时间间隔(100ms)
     * @param [in] Times : uint [default:1] 鸣叫次数
     */
    LC_CMD_METHOD(BuzzerControl)
    {
        uint duration = arg["Duration"].To<uint>(1);
        uint interval = arg["Interval"].To<uint>(0);
        uint times = arg["Times"].To<uint>(1);
        
        return _reader.BuzzerControl(duration, interval, times);
    }
    /**
     * @brief LED控制
     * @date 2017-02-11 15:04
     * 
     * @param [in] IsTurnOn : bool [default:false] 是否需要打开LED
     * @param [in] IsRed : bool [default:false] 是否需要打开红灯
     * @param [in] IsGreen : bool [default:false] 是否需要打开绿灯
     */
    LC_CMD_METHOD(LedControl)
    {
        bool isTurnOn = arg["IsTurnOn"].To<bool>(false);
        bool isRed = arg["IsRed"].To<bool>(false);
        bool isGreen = arg["IsGreen"].To<bool>(false);

        return _reader.LedControl(isTurnOn, isRed, isGreen);
    }
    /**
     * @brief 设置设备为升级模式
     * @date 2017-02-11 15:07
     */
    LC_CMD_METHOD(SetUpdateMode)
    {
        return _reader.SetUpdateMode();
    }
    /**
     * @brief 设置设备是否自动处理61,6C
     * @date 2017-02-11 15:07
     * 
     * @param [in] IsHandle 是否需要自动处理61,6C
     */
    LC_CMD_METHOD(SetSW_Mode)
    {
        bool isHandle = arg["IsHandle"].To<bool>(false);
        return _reader.SetSW_Mode(isHandle);
    }
    /**
     * @brief 获取非接卡片的数目
     * @date 2017-02-11 15:08
     * 
     * @retval Count : uint 获取到的卡片数目
     */
    LC_CMD_METHOD(GetContactlessCardCount)
    {
        size_t count = 0;
        if(!_reader.GetContactlessCardCount(count))
            return false;

        rlt.Put("Count", ArgConvert::ToString(count));
        return true;
    }
    /**
     * @brief 关闭设备天线(上电时设备会自动启动)
     * @date 2017-04-22 11:17
     */
    LC_CMD_METHOD(HaltAerial)
    {
        return _reader.HaltAerial();
    }
};
//--------------------------------------------------------- 
} // nemespace driver
} // namespace application
} // namespace zhou_yb
//--------------------------------------------------------- 
#endif // _LIBZHOUYB_DEVREADER_CMDDRIVER_H_
//========================================================= 